home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / 3dvect37.zip / 3D1.ASM < prev    next >
Assembly Source File  |  1994-06-22  |  36KB  |  1,169 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ;
  3. ; Filename     : 3d1.asm
  4. ; Included from: Main Assembley Module
  5. ; Description  : 3d vector routines - fast sort method
  6. ;
  7. ; Written by: John McCarthy
  8. ;             1316 Redwood Lane
  9. ;             Pickering, Ontario.
  10. ;             Canada, Earth, Milky Way (for those out-of-towners)
  11. ;             L1X 1C5
  12. ;
  13. ; Internet/Usenet:  BRIAN.MCCARTHY@CANREM.COM
  14. ;         Fidonet:  Brian McCarthy 1:229/15
  15. ;   RIME/Relaynet: ->CRS
  16. ;
  17. ; Home phone, (905) 831-1944, don't call at 2 am eh!
  18. ;
  19. ; Send me your protected mode source code!
  20. ; Send me your Objects!
  21. ; But most of all, Send me a postcard!!!!
  22. ;
  23. ; - objects cannot enter inside one another
  24. ; - maxsurfs and maxpoints can be kept low - set to largest object requirement
  25. ;
  26. ; To use:
  27. ;
  28. ;          call draw_landscape     ; draw background landscape
  29. ;          call clear_fill         ; clear video memory (last screen)
  30. ;          call look_at_it         ; make camera look at selected object
  31. ;          call setsincose         ; set rotation multipliers for eye
  32. ;          call show_stars         ; plot background stars (if you want)
  33. ;          call makeobjs           ; plot all objects on current screen
  34. ;          call instant_mouse      ; plot mouse on screen
  35. ;          call flip_page          ; flip video pages
  36. ;          call resetupd           ; reset update for borders
  37. ;          call updvectors         ; move objects around, rotate them
  38. ;
  39. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  40.  
  41.            .386p
  42.            jumps
  43.  
  44. code32     segment para public use32
  45.            assume cs:code32, ds:code32
  46.  
  47. ; define externals
  48.  
  49.            include pmode.ext       ; protected mode externals
  50.            include xmouse.ext      ; xmode mouse externals
  51.            include xmode.ext       ; xmode externals by matt pritchard
  52.            include irq.ext
  53.            include font.ext
  54.  
  55.            include macros.inc
  56.            include equ.inc
  57.  
  58.            include vars1.inc       ; labels and such
  59.            align 16
  60.            include arctan.inc      ; inverse tan
  61.            include sin.inc         ; sin/cosin table
  62.            include math.inc        ; rotate, cos,sin,arctan...
  63.            include xscale.inc
  64.            include poly.inc        ; common ploygon stuff
  65.            include more.inc        ; more common 3d/graphics stuff
  66.  
  67.            public makeobjs
  68.            public make1obj
  69.            public flush_surfaces
  70.            public init_tables
  71.  
  72. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  73. ; Loadpoints:  Begin loading of points from object definition data into array
  74. ; In:
  75. ;  ESI -> object #
  76. ; Out:
  77. ;  ESI -> offset of connection data
  78. ; Given ESI as object number.  rotate, translate and convert to 3d the points
  79. ; of that object.  returns edi as pointer to sides.
  80. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  81.  
  82.            align 16
  83.  
  84. loadpoints:
  85.            mov bl,userotate[esi]  ; rotation type
  86.  
  87.            mov si,whatshape[esi*2] ; get shape
  88.            mov esi,objbase[esi*4]
  89.  
  90. view_is_not_ok:
  91.            mov eax,[esi]
  92.            add esi,8
  93.  
  94.            cmp eax,zad            ; check if too far to see detail anyway
  95.            jb s view_is_not_ok
  96.  
  97.            mov eax,[esi-4]
  98.            add esi,eax
  99.  
  100.            lodsd
  101.            mov w numpoints,ax
  102.            or ax,ax
  103.            jz no_points_anyway    ; object is made totally out of iterations...
  104.            shr eax,16
  105.            mov numsides,eax
  106.            add esi,50             ; skip extra data
  107.  
  108.            mov edi,4              ; reset xp pointer
  109. middle_load_points:
  110.            test bl,no_rotation
  111.            jnz s np13             ; use different loop if no rotation
  112. np12:
  113.            movsx ebx,w [esi]      ; x
  114.            movsx ecx,w [esi+2]    ; y
  115.            movsx ebp,w [esi+4]    ; z
  116.  
  117.            push edi esi
  118.            call rotate            ; rotate
  119.            add ebp,zad
  120.  
  121.            cmp ebp,ztruncate
  122.            jge s ntrunct
  123.            neg ebp
  124.            cmp ebp,ztruncate
  125.            jge s ntrunct
  126.            mov ebp,ztruncate
  127. ntrunct:
  128.            add ebx,xad
  129.            add ecx,yad
  130.            call make3d
  131.            pop esi edi
  132.            mov xp[edi],ebx
  133.            mov yp[edi],ecx
  134.            mov zp[edi],ebp
  135.            add edi,4              ; inc xp indexer
  136.            add esi,6              ; inc input pointer
  137.            dec numpoints
  138.            jne s np12
  139.  
  140.            mov pointindex,edi     ; save in case of iteration surfaces
  141.  
  142.            ret                    ; edi exits with pointer to sides
  143.  
  144. no_points_anyway:
  145.            mov pointindex,4       ; side is all iteration surfaces
  146.            shr eax,16
  147.            mov numsides,eax
  148.            add esi,25*2           ; skip extra data
  149.            ret
  150. np13:
  151.            movsx ebx,w [esi]      ; x
  152.            movsx ecx,w [esi+2]    ; y
  153.            movsx ebp,w [esi+4]    ; z
  154.  
  155.            push edi esi
  156.            call erotate           ; rotation matrix already set up! (camera)
  157.            add ebp,zad
  158.  
  159.            cmp ebp,ztruncate
  160.            jge s ntrunct2
  161.            neg ebp
  162.            cmp ebp,ztruncate
  163.            jge s ntrunct
  164.            mov ebp,ztruncate
  165. ntrunct2:
  166.            add ebx,xad
  167.            add ecx,yad
  168.            call make3d
  169.            pop esi edi
  170.            mov xp[edi],ebx
  171.            mov yp[edi],ecx
  172.            mov zp[edi],ebp
  173.            add edi,4              ; inc xp indexer
  174.            add esi,6
  175.            dec numpoints
  176.            jne s np13
  177.  
  178.            mov pointindex,edi     ; save in case of iteration surfaces
  179.  
  180.            ret
  181.  
  182. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  183. ; Special surface types/options - make your own
  184. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  185.  
  186.            align 16
  187.  
  188. special_commands dd offset dobitmap        ; 0
  189.                  dd offset dobitmap        ; 1
  190.                  dd offset pushmatrix      ; 2
  191.                  dd offset popmatrix       ; 3
  192.                  dd offset pushlocation    ; 4
  193.                  dd offset poplocation     ; 5
  194.                  dd offset newobject       ; 6
  195.                  dd offset no_new_matrix   ; 7
  196.                  dd offset gosub_function  ; 8
  197.                  dd offset return_function ; 9
  198.                  dd offset goto_function   ; 10
  199.  
  200. number_ofb dw 5*2 ; hibitmap
  201.            dw 5*2 ; lobitmap
  202.            dw 1*2 ; pushmatrix
  203.            dw 1*2 ; popmatrix
  204.            dw 1*2 ; pushlocation
  205.            dw 1*2 ; poplocation
  206.            dw 1*2 ; newobject
  207.            dw 1*2 ; no_new_matrix
  208.            dw ?   ; gosub_function
  209.            dw ?   ; return_function
  210.            dw ?   ; goto_function
  211.  
  212.            align 16
  213. gosub_function:
  214.            push esi
  215.            movsx eax,w [esi]
  216.            add esi,eax
  217.            jmp return_iteration
  218.  
  219.            align 16
  220. return_function:
  221.            pop esi
  222.            add esi,2
  223.            jmp return_iteration
  224.  
  225.            align 16
  226. goto_function:
  227.            movsx eax,w [esi]
  228.            add esi,eax
  229.            jmp return_iteration
  230.  
  231.            align 16
  232. pushmatrix:
  233.            push vmatrix+0
  234.            push vmatrix+4
  235.            push vmatrix+8
  236.            push vmatrix+12
  237.            push vmatrix+16
  238.            push vmatrix+20
  239.            push vmatrix+24
  240.            push vmatrix+28
  241.            push vmatrix+32
  242.            jmp return_iteration
  243.  
  244.            align 16
  245. popmatrix:
  246.            pop vmatrix+32
  247.            pop vmatrix+28
  248.            pop vmatrix+24
  249.            pop vmatrix+20
  250.            pop vmatrix+16
  251.            pop vmatrix+12
  252.            pop vmatrix+8
  253.            pop vmatrix+4
  254.            pop vmatrix+0
  255.            jmp return_iteration
  256.  
  257.            align 16
  258. pushlocation:
  259.            push xad
  260.            push yad
  261.            push zad
  262.            jmp return_iteration
  263.  
  264.            align 16
  265. poplocation:
  266.            pop zad
  267.            pop yad
  268.            pop xad
  269.            jmp return_iteration
  270.  
  271.            align 16
  272. ld_special:
  273.            mov ecx,eax
  274.            and ecx,special-1      ; maximum 127 "special" commands
  275.            jmp [special_commands+ecx*4]
  276.  
  277.            align 16
  278.  
  279. ; handle loading of bitmap from object list
  280. ;
  281. ; eg dw himap,8,5,50,60 ;command is 32,point 8, bitmap 5, x&y scaling of 50,60
  282.  
  283. dobitmap:
  284.            lodsw                  ; get from si, first is point
  285.            shl eax,2
  286.            stosw                  ; put in sides table
  287.  
  288.            mov edx,ebp            ; save indexer
  289.            movzx ebp,ax           ; get point indexers
  290.            mov eax,zp[ebp]
  291.            mov zeds[ebx*2],eax    ; set zed for sort.
  292.            mov ebp,edx
  293.  
  294.            movsw                  ; get bitmap type
  295.            movsd                  ; get x then y scaling
  296.  
  297.            mov edx,command        ; get command (for iteration bits)
  298.            mov textures[ebx],dx   ; command is now texture
  299.  
  300.            jmp ln3
  301.  
  302. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  303. ; Loadsides: Load connection data from object data definition
  304. ; In:
  305. ;  ESI -> offset of connection data
  306. ; Out: null
  307. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  308.  
  309.            align 16
  310. loadsides:
  311.            mov showing,0          ; reset counter/indexer
  312.            mov lamflag,no
  313.  
  314.            xor ebp,ebp            ; indexer to first point
  315.            mov edi,offset sides   ; get ready for lodsw and stosw
  316.            xor ebx,ebx
  317. ld_lp:
  318.            lodsw                  ; get command word
  319.            mov command,eax
  320.            mov edx,eax            ; save for later test
  321.  
  322.            mov order[ebx*2],ebx   ; set order to 0,2,4,6,8...
  323.  
  324.            test eax,special       ; if bitmap, do special load, or previous
  325.            jnz ld_special         ; colour (avoids pre-fetch instruction flush)
  326.  
  327.            mov eax,[esi]          ; get texture data/type
  328.            mov texture12,eax
  329.  
  330.            mov eax,[esi+4]        ; get colour, high byte is other side
  331.            add esi,8
  332.            mov colors12,eax
  333.  
  334.            push ebp
  335.            push ebx
  336.  
  337.            movzx eax,w [esi]      ; get from esi, first is unconditinal
  338.            add esi,2
  339.            shl eax,2
  340.            mov [edi],ax           ; put in edi
  341.            add edi,2
  342.            mov ecx,eax
  343. ld_loop:
  344.            lodsw                  ; get from esi
  345.            shl eax,2
  346.            mov [edi],ax           ; put in edi
  347.            cmp eax,ecx            ; check all after first point
  348.            je s ld_exitloop
  349.  
  350.            lodsw
  351.            shl eax,2
  352.            mov [edi+2],ax
  353.            cmp eax,ecx
  354.            je s ld_exitloop
  355.  
  356.            lodsw
  357.            shl eax,2
  358.            mov [edi+4],ax
  359.            cmp eax,ecx
  360.            je s ld_exitloop
  361.  
  362.            lodsw
  363.            shl eax,2
  364.            mov [edi+6],ax
  365.            add edi,8
  366.            cmp eax,ecx
  367.            jne s ld_loop
  368.  
  369. ld_exitloop:
  370.            push esi
  371.            mov edi,ebp            ; adjust bp into appropriate indexer
  372.            mov bp,[sides+edi+2]   ; get point indexers
  373.            mov ecx,[zp+ebp]       ; take average of two z values, should be
  374.            mov bp,[sides+edi+0]   ; average of all but two is ok.
  375.            add ecx,[zp+ebp]
  376.            mov zeds[ebx*2],ecx    ; but any will do.
  377.  
  378.            test edx,onscr         ; find if test is for on screen pixels
  379.            jnz test_if_on_screen
  380.            test dl,both           ; check if always visible (or point, or line)
  381.            jnz its_line
  382.  
  383. return_screen:
  384.            mov edx,[xp+ebp]       ; first point
  385.            mov ebx,[yp+ebp]
  386.  
  387.            mov bp,[sides+edi+2]
  388.            mov esi,[xp+ebp]       ; second point
  389.            mov ecx,[yp+ebp]
  390.  
  391.            mov bp,[sides+edi+4]
  392.            mov edi,[xp+ebp]       ; third point
  393.            mov ebp,[yp+ebp]
  394.  
  395.            call checkfront        ; check if side is visible using p1,2,3
  396.  
  397.            pop esi ebx ebp
  398.  
  399.            mov edx,command
  400.            or ecx,ecx
  401.            jle s test_shading     ; cx>-1 if side visible, skip if not
  402.            test edx,double        ; test to use other colour
  403.            jz s skipit            ; miss this side...
  404.            shr texture12,16
  405.            shr colors12,16
  406.            xor w texture12,inverse ; do inverse shading
  407. test_shading:
  408.            test texture12,shade+last
  409.            jnz handle_shading     ; shading bit set, do it...
  410. ln2:
  411.            test edx,check         ; find out if side is only a test side
  412.            jnz s no_show
  413.  
  414.            mov eax,texture12      ; another side added...
  415.            mov textures[ebx],ax
  416.            movzx eax,w colors12
  417.            add eax,palxrefx       ; get offset of palette cross reference table for this object
  418.            mov ax,[eax]
  419.            mov surfcolors[ebx],ax
  420. ln3:
  421.            inc showing
  422.            add ebx,2
  423.            add ebp,maxpolys*2     ; bump ebp to next block
  424. no_show:
  425.            test edx,iterate
  426.            jnz handle_surface_iteration
  427. skipit:
  428.            test edx,normal        ; do we skip surface normal data
  429.            jz s no_norml
  430.            add esi,6
  431. no_norml:
  432.            test edx,iterate
  433.            jnz failed_iteration   ; skip iteration data if surface failure
  434.  
  435. return_iteration:
  436.            mov edi,ebp            ; set di for next stosw
  437.            add edi,offset sides
  438.  
  439.            dec numsides           ; count for next side
  440.            jne ld_lp
  441.  
  442.            ret
  443.  
  444.            align 16
  445. its_line:
  446.            pop esi ebx ebp
  447.            test w texture12,shade+last
  448.            jz ln2
  449.  
  450. ; handle gourad/lambert shading
  451.  
  452.            align 16
  453. handle_shading:
  454.            test w texture12,last  ; test to use previous colour or bitmap call
  455.            jnz ld_do_previous
  456.  
  457.            test w texture12,wavey
  458.            jnz ln2
  459.  
  460.            push ebx esi ebp edx
  461.  
  462.            cmp lamflag,no         ; is lambert matrix set up?
  463.            je s setitup           ; jump to less likely route
  464. returnq:
  465.            mov bx,word ptr [esi]  ; get surface normal
  466.            mov cx,word ptr [esi+2]
  467.            mov bp,word ptr [esi+4]
  468.            add esi,6
  469.  
  470.            call lrotate           ; rotate surface normal by lambert matrix
  471.  
  472.            pop edx
  473.            test w texture12,inverse ; have the sides flipped?
  474.            jnz s invert_colour    ; jump to least likely route
  475. lp_contin:
  476.            add edi,256
  477.            shr edi,1              ; result -256 to +256, turn into 0-256
  478.            mov al,b shading_tables[edi] ; now into 0-15
  479.            xor ah,ah
  480.  
  481.            pop ebp esi ebx
  482.  
  483.            add w colors12,ax      ; user can have offset color in object!
  484.  
  485.            jmp ln2
  486.  
  487.            align 16
  488. invert_colour:                    ; inversion occures with other side option,
  489.            neg edi                ; always visible option, and shading option
  490.            jmp lp_contin          ; all combined!
  491.  
  492.            align 16
  493. setitup:
  494.            push esi
  495.            mov esi,currobj        ; this is object # from make1obj
  496.            call lambert           ; set up lambert maxtrix
  497.            mov lamflag,yes
  498.            pop esi
  499.            jmp s returnq
  500.  
  501.            align 16
  502.  
  503. ld_do_previous:
  504.            mov ax,w colors12
  505.            mov cx,surfcolors[ebx-2]
  506.            and cx,shading_bits    ; drop old colour block, keep shading indexer (from math.inc)
  507.            add ecx,eax            ; add new colour block
  508.            mov w colors12,cx
  509.  
  510.            jmp ln2
  511.  
  512. ; handle iteration option
  513.  
  514.            align 16
  515.  
  516. handle_surface_iteration:
  517.            test edx,normal
  518.            jz s no_norml2
  519.            add esi,6              ; skip if shading normal present
  520. no_norml2:
  521.            test edx,matrix        ; test to derive new matrix
  522.            jz no_new_matrix
  523. newobject:
  524.            mov edi,currobj        ; new matrix, get offset object number
  525.            add di,[esi+16]
  526.            test onoff[edi],sub_object_on ; test if sub-object has been turned on...
  527.            jz failed_iteration
  528.  
  529.            mov eax,[esi+24]
  530.            mov minzc,eax
  531.            mov eax,[esi+28]
  532.            mov btolr,eax
  533.            push ebx esi ebp edx   ; save stuff before iteration handle
  534.  
  535.            mov bx,w xs[edi*4]     ; get rotation location
  536.            mov cx,w ys[edi*4]
  537.            mov bp,w zs[edi*4]
  538.            add bx,[esi+10]
  539.            add cx,[esi+12]
  540.            add bp,[esi+14]
  541.            movsx ebx,bx
  542.            movsx ecx,cx
  543.            movsx ebp,bp
  544.  
  545.            push edi
  546.            call rotate            ; z<>0, find rotation location
  547.  
  548.            add xad,ebx
  549.            add yad,ecx
  550.            add zad,ebp
  551.  
  552.            pop esi                ; return object number+offset
  553.            test userotate[esi],no_rotation ; test to use new matrix or add to old
  554.            jnz do_compound_thingy
  555.            call temp_matrix       ; add to old
  556.            call matrix_multiply
  557.            mov eax,minzc
  558.            cmp zad,eax            ; check if new object will be behind camera
  559.            jg done_alterq
  560.            jmp failed_iterationq
  561.  
  562. do_compound_thingy:
  563.            call compound          ; compound new matrix
  564.            mov eax,minzc
  565.            cmp zad,eax            ; check if new object will be behind camera
  566.            jg done_alterq
  567.            jmp failed_iterationq
  568.  
  569. no_new_matrix:
  570.            test b [esi+8],centroid ; is there a centroid offset?
  571.            jz done_alter
  572.            mov eax,[esi+28]
  573.            mov btolr,eax
  574.  
  575.            push ebx esi ebp edx   ; save stuff before centroid handle
  576.            movsx ebx,w [esi+10]   ; no new matrix command, find point
  577.            movsx ecx,w [esi+12]   ; offset (addition)
  578.            movsx ebp,w [esi+14]
  579.  
  580.            call rotate            ; if found, add rotated point to xad,yad,zad
  581.  
  582.            add xad,ebx
  583.            add yad,ecx
  584.            add zad,ebp
  585.  
  586. done_alterq:
  587.            sub zad,1              ; prevent huge object from becoming 0
  588.            adc zad,1
  589.  
  590.            mov ebx,xad            ; test if new xad,yad,zad are within screen boundaries
  591.            mov ecx,yad
  592.            mov ebp,zad
  593.  
  594.            cmul eax,ebx,ratiox    ; use fast constant multiply fo 3d conversion
  595.            idiv ebp
  596.  
  597.            movsx edx,xmins
  598.            sub edx,btolr
  599.            cmp eax,edx            ; tolerance is max object size/ratio
  600.            jl failed_iterationq
  601.            movsx edx,xmaxs
  602.            add edx,btolr
  603.            cmp eax,edx
  604.            jge failed_iterationq
  605.  
  606.            mov ebx,eax
  607.  
  608.            cmul eax,ecx,ratioy
  609.            idiv ebp
  610.  
  611.            movsx edx,ymins
  612.            sub edx,btolr
  613.            cmp eax,edx
  614.            jl failed_iterationq
  615.            movsx edx,ymaxs
  616.            add edx,btolr
  617.            cmp eax,edx
  618.            jge failed_iterationq
  619.  
  620.            mov edi,pointindex
  621.            mov xp[edi],ebx
  622.            mov yp[edi],eax
  623.            mov zp[edi],ebp
  624.            add pointindex,4
  625.  
  626.            pop edx ebp esi ebx
  627.  
  628. done_alter:
  629.            movzx eax,w [esi]      ; get number of extra points in iteration
  630.            add esi,2
  631.            mov numpoints,eax      ; set as counter
  632.            mov ecx,eax            ; save number of extra points for later use
  633.  
  634.            shl eax,2
  635.            add eax,pointindex     ; pointindex = word indexer to last point
  636.            cmp eax,maxpoints*4    ; test for overflow in points tables
  637.            jae abort_all2
  638.  
  639.            lodsw                  ; get number of sides in iteration
  640.            add numsides,eax
  641.  
  642.            add eax,showing
  643.            cmp eax,maxsurfaces-1  ; check for overflow in "sides" tables
  644.            jae abort_all2
  645.  
  646.            add esi,25*2
  647.  
  648.            or ecx,ecx             ; no new points to add? (just surfaces)
  649.            je return_iteration    ; only sides added to iteration, done...
  650.  
  651.            push ebx ebp edx       ; save load and store locations
  652.  
  653.            mov edi,currobj        ; add more points to xp,yp,zp list
  654.            mov bl,userotate[edi]  ; because iteration is visible
  655.  
  656.            mov edi,pointindex     ; movzx edi,pointindex
  657.  
  658.            call middle_load_points
  659.            pop edx ebp ebx
  660.  
  661.            jmp return_iteration
  662.  
  663.            align 16
  664.  
  665. abort_all2:
  666.            ret                    ; out of room for surfaces, return and plot
  667.  
  668. ; perform test for option "onscr" - test if polygon points on screen.
  669. ; routine also tests if polygon crosses screen - eg no point is on the screen
  670. ; but the polygon covers the screen, like the front of a very big building.
  671.  
  672.            align 16
  673.  
  674. test_if_on_screen:
  675.            xor bl,bl              ; bl = quadrant flag
  676.            push edx edi           ; save command
  677.  
  678.            mov esi,ebp
  679. tios:
  680.            mov ecx,xp[esi]        ; cx, dx =(x,y) to test
  681.            mov edx,yp[esi]
  682.  
  683.            mov ah,32              ;  32 16  8    determine where point is,
  684.            cmp cx,xmins           ;1  x  x  x    then or bl with location
  685.            jl s ytest             ;2  x  x  x
  686.            mov ah,8               ;4  x  x  x
  687.            cmp cx,xmaxs           ;
  688.            jge s ytest
  689.            mov ah,16
  690. ytest:
  691.            mov al,1
  692.            cmp dx,ymins
  693.            jl s oritall
  694.            mov al,4
  695.            cmp dx,ymaxs
  696.            jge s oritall
  697.  
  698.            cmp ah,16
  699.            je s on_screen         ; a point is on the screen, generate side...
  700.            mov al,2
  701. oritall:
  702.            or bl,ah               ; point is not on the screen, but it may
  703.            or bl,al               ; contribute to a polygon which covers the screen.
  704.  
  705.            add edi,2              ; get next connection for another test
  706.            mov si,sides[edi]
  707.            cmp si,bp              ; test if at last connection in iteration test
  708.            jne tios
  709.  
  710.            xor al,al              ; count number of bits in y (must be >2)
  711.            ror bl,1
  712.            adc al,0
  713.            ror bl,1
  714.            adc al,0
  715.            ror bl,1
  716.            adc al,0
  717.            cmp al,1
  718.            jbe s skipit2
  719.  
  720.            xor al,al              ; now count x (must be >2)
  721.            ror bl,1
  722.            adc al,0
  723.            ror bl,1
  724.            adc al,0
  725.            ror bl,1
  726.            adc al,0
  727.            cmp al,1
  728.            jbe s skipit2
  729. on_screen:
  730.            pop edi edx
  731.  
  732.            test edx,both          ; side is on screen
  733.            jz return_screen       ; test if alway visible
  734.  
  735.            pop esi ebx ebp        ; always, pop and test for shading
  736.            test edx,shade
  737.            jz ln2                 ; no shading - do normal return
  738.            jmp handle_shading
  739.  
  740. skipit2:
  741.            pop edi edx esi ebx ebp
  742.            jmp skipit
  743.  
  744. ; handle failure of iteration option
  745.  
  746.            align 16
  747.  
  748. failed_iterationq:
  749.            pop edx ebp esi ebx
  750.  
  751. failed_iteration:
  752.            movzx ecx,w [esi+4]    ; number of bytes to skip in case of failure
  753.            mov ax,[esi+6]         ; get number of points TOTAL in iteration
  754.            add esi,8
  755.            shl eax,2              ; in case iteration in iteration in iteration...
  756.            add w pointindex,ax
  757.            add esi,ecx
  758.            jmp return_iteration
  759.  
  760.            align 16
  761.  
  762. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  763. ; Make1obj: Handle plotting of object ESI
  764. ; In:
  765. ;   ESI -> object #
  766. ; OUT:null
  767. ; Notes:
  768. ; Routine assumes object is already ON!  note: esi not si!
  769. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  770.  
  771. make1obj:
  772.            mov currobj,esi
  773.  
  774.            mov ebx,xs[esi*4]        ; displacement
  775.            sub ebx,eyex
  776.            mov ecx,ys[esi*4]
  777.            sub ecx,eyey
  778.            mov ebp,zs[esi*4]
  779.            sub ebp,eyez
  780.  
  781.            test userotate[esi],s_himap+s_point ; check if bitmap or point
  782.            jnz mo_special
  783.  
  784.            shr ebx,8              ; account for decimal places
  785.            test ebx,00800000h
  786.            jz s pm_1
  787.            or ebx, 0ff000000h
  788. pm_1:
  789.            shr ecx,8
  790.            test ecx,00800000h
  791.            jz s pm_2
  792.            or ecx, 0ff000000h
  793. pm_2:
  794.            shr ebp,8
  795.            test ebp,00800000h
  796.            jz s pm_3
  797.            or ebp, 0ff000000h
  798. pm_3:
  799.            mov si,whatshape[esi*2] ; get shape
  800.            mov esi,objbase[esi*4] ; get header start
  801.            add esi,[esi+4]        ; get first resolution
  802.            mov edi,[esi+14*2]     ; get maximum distance seen
  803.  
  804.            cmp ebx,edi            ; check if within visible space
  805.            jnl s noa2             ; if object miles away, don't bother
  806.            cmp ebp,edi
  807.            jnl s noa2
  808.            cmp ecx,edi
  809.            jnl s noa2
  810.            neg edi
  811.            cmp ebp,edi
  812.            jl s noa2
  813.            cmp ebx,edi
  814.            jl s noa2
  815.            cmp ecx,edi
  816.            jg s mo_misout
  817. noa2:
  818.            ret
  819. mo_misout:
  820.            mov edi,dword ptr [esi+16*2]
  821.            mov eax,dword ptr [esi+18*2]
  822.            mov btolr,eax
  823.            call zsolve            ; figure out camera displacement
  824.  
  825.            cmp esi,edi            ; check if behind camera, miminum dist.
  826.            jl s noa2
  827.  
  828.            sub esi,1              ; make z non-zero
  829.            adc esi,1
  830.  
  831.            call xsolve
  832.            mov xad,edi            ; store 3d offsets
  833.            call make3dx           ; now make object farther in 3d
  834.  
  835.            movsx eax,xmins
  836.            sub eax,btolr
  837.            cmp edi,eax            ; tolerance is max object size/ratio
  838.            jl s noa2
  839.            movsx eax,xmaxs
  840.            add eax,btolr
  841.            cmp edi,eax
  842.            jge s noa2
  843.  
  844.            call ysolve            ; solve y and set correct regs
  845.            mov yad,ecx
  846.            call make3dy           ; now make object farther in 3d
  847.  
  848.            movsx eax,ymins
  849.            sub eax,btolr
  850.            cmp ecx,eax
  851.            jl noa2
  852.            movsx eax,ymaxs
  853.            add eax,btolr
  854.            cmp ecx,eax
  855.            jge noa2
  856.  
  857.            mov zad,ebp
  858.            mov zedthis,ebp        ; store z for next sort
  859.  
  860.            mov xp,ebx             ; save center of gravity as point 0
  861.            mov yp,ecx
  862.            mov zp,ebp
  863.  
  864.            mov esi,currobj        ; pop original object number
  865.            xor ebx,ebx
  866.            mov bl,palxref[esi]
  867.            mov ebx,xreftable[ebx*4]
  868.            mov palxrefx,ebx
  869.  
  870.            test userotate[esi],no_rotation    ; test to call compound routine
  871.            jnz s mk_skipc         ; skip if anything other than full rotations
  872.            call compound          ; full rotation object, calc. matrix
  873. mk_skipc:
  874.            call loadpoints        ; load points and rotate, exit di=sides
  875.            call loadsides         ; now load sides, starting at di
  876.            call sort_list         ; sort surfaces
  877.            jmp  drawvect          ; draw surfaces and exit
  878. noa:
  879.            ret
  880.  
  881. ; if userotate = "bitmap" then draw bitmap at location x,y,z
  882.  
  883.            align 16
  884.  
  885. mo_special:
  886.            mov edi,maxz*256
  887.            cmp ebx,edi            ; check if within visible space
  888.            jnl s noa              ; if object miles away, don't bother
  889.            cmp ebp,edi
  890.            jnl s noa
  891.            cmp ecx,edi
  892.            jnl s noa
  893.            neg edi
  894.            cmp ebp,edi
  895.            jl s noa
  896.            cmp ebx,edi
  897.            jl s noa
  898.            cmp ecx,edi
  899.            jl s noa
  900.  
  901.            shr ebx,8              ; account for decimal places, /256
  902.            test ebx,00800000h
  903.            jz s pq_1
  904.            or ebx, 0ff000000h
  905. pq_1:
  906.            shr ecx,8
  907.            test ecx,00800000h
  908.            jz s pq_2
  909.            or ecx, 0ff000000h
  910. pq_2:
  911.            shr ebp,8
  912.            test ebp,00800000h
  913.            jz s pq_3
  914.            or ebp, 0ff000000h
  915. pq_3:
  916.  
  917.            call zsolve            ; figure out camera displacement
  918.  
  919.            cmp esi,minz           ; check if behind camera, miminum dist.
  920.            jl noa2
  921.  
  922.            call xsolve
  923.            mov xad,edi            ; store 3d offsets
  924.            call make3dx           ; now make object farther in 3d
  925.  
  926.            cmp edi,xmit           ; tolerance is max object size/ratio
  927.            jl noa
  928.            cmp edi,xmat
  929.            jge noa
  930.  
  931.            call ysolve            ; solve y and set correct regs
  932.            mov yad,ecx
  933.            call make3dy           ; now make object farther in 3d
  934.  
  935.            cmp ecx,ymit
  936.            jl noa
  937.            cmp ecx,ymat
  938.            jge noa
  939.  
  940.            mov zad,ebp
  941.            mov zedthis,ebp        ; store z for next sort
  942.            mov esi,currobj        ; pop original object number
  943.  
  944.            mov al,userotate[esi]
  945.            test al,s_point        ; check if point
  946.            jnz mo_ispoint
  947.  
  948.            push eax ebx ecx       ; save actual center of bitmap and command
  949.  
  950.            mov ebx,xad            ; calc size of bitmap
  951.            mov ecx,yad
  952.  
  953.            shl esi,1              ; si = word
  954.            movzx edx,vxs[esi]     ; get addition for bitmap size
  955.            sub ebx,edx
  956.            sub ecx,edx
  957.  
  958.            mov si,whatshape[esi]
  959.            shl esi,2              ; si = dword
  960.            sub ebx,bitx[esi]
  961.            sub ecx,bity[esi]      ; ebx,ecx = top corner of bitmap in 3d
  962.  
  963.            mov eax,bitbase[esi]
  964.            mov bitmap,eax
  965.  
  966.            call make3d            ; ebx,ecx = top corner of bitmap in 2d
  967.  
  968.            if useborders eq yes
  969.  
  970.            cmp cx,yupdate+0
  971.            jge s up_no12
  972.            mov yupdate+0,cx
  973. up_no12:
  974.            cmp bx,xupdate+0
  975.            jge s up_no32
  976.            mov xupdate+0,bx
  977. up_no32:
  978.            endif
  979.  
  980.            pop ebp eax            ; bp = y, ax = x center
  981.            sub bp,cx              ; bp = y height/2
  982.            sub ax,bx              ; ax = x width/2
  983.  
  984.            if useborders eq yes
  985.            mov dx,cx
  986.            mov di,bx
  987.            endif
  988.  
  989.            add bx,xcent
  990.            add cx,ycent
  991.            mov destx,bx
  992.            mov desty,cx
  993.  
  994.            shl bp,1
  995.            shl ax,1
  996.  
  997.            mov destheight,bp
  998.            mov destwidth,ax
  999.  
  1000.            if useborders eq yes
  1001.            add dx,bp
  1002.            add di,ax
  1003.  
  1004.            cmp dx,yupdate+2
  1005.            jng s up_no42
  1006.            mov yupdate+2,dx
  1007. up_no42:
  1008.            cmp di,xupdate+2
  1009.            jng s up_no22
  1010.            mov xupdate+2,di
  1011. up_no22:
  1012.            endif
  1013.  
  1014.            pop eax
  1015.            test al,lomap-himap   ; test to use 1/4 scale bitmap or full scale
  1016.            jz xscale2
  1017.            jmp xscale4
  1018. noa7:
  1019.            ret
  1020. mo_ispoint:
  1021.            cmp bx,xmins            ; draw single point/bullet
  1022.            jl s noa7
  1023.            cmp bx,xmaxs
  1024.            jge s noa7
  1025.            cmp cx,ymins
  1026.            jl s noa7
  1027.            cmp cx,ymaxs            ; ymaxs1 if larger pixel
  1028.            jge s noa7
  1029.  
  1030.            mov edi, current_page   ; point to active vga page
  1031.            add bx,xcent
  1032.            add cx,ycent
  1033.  
  1034.            mov si,cx
  1035.            mov eax,[esi*4+fastimultable] ; get offset to start of line
  1036.  
  1037.            mov cx, bx              ; copy to extract plane # from
  1038.            shr bx, 2               ; x offset (bytes) = xpos/4
  1039.            add bx, ax              ; offset = width*ypos + xpos/4
  1040.  
  1041.            mov ax, map_mask_plane1 ; map mask & plane select register
  1042.            and cl, plane_bits      ; get plane bits
  1043.            shl ah, cl              ; get plane select value
  1044.            out_16 sc_index, ax     ; select plane
  1045.  
  1046.            movzx ebx,bx
  1047.            mov [edi+ebx],b bulletcolour ; draw pixel, red or yellow is good
  1048. ;          add edi,xactual/4
  1049. ;          mov [edi+ebx],b bulletcolour2 ; draw larger bullet/pixel
  1050.  
  1051. ; if drawing larger pixel, change above code to this!
  1052. ;          cmp cx,ymaxs1
  1053. ;          jge s noa7
  1054.  
  1055.            ret
  1056.  
  1057.            align 16
  1058.  
  1059. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1060. ; Setmakeorder: Initialize original order for plotting objects
  1061. ;  In=Out=null
  1062. ; Notes:  This is called by init_tables so there is no need for you to do it.
  1063. ; This  must  be  called  once  at  the  beginging of the program  to  define
  1064. ; in what order the objects must be plotted (back to front).   The  order  is
  1065. ; constantly being re-arranged as objects move in front an behind one another
  1066. ; If you want to do windowing, save the makeorder table for each window.
  1067. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1068.  
  1069. set_makeorder:
  1070.  
  1071.            i=0
  1072.            rept maxobjects        ; macro to produce unrolled loop
  1073.            mov makeorder+i*2,i+1  ; set makeorder to 0,1,2,3,4
  1074.            i=i+1
  1075.            endm
  1076.  
  1077.            ret
  1078.  
  1079.            align 16
  1080.  
  1081. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1082. ; Makeobjs: Make/plot all objects on current_page
  1083. ;  In=Out=null
  1084. ; Notes: Called from your mainline animation routine, falls through to sort
  1085. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1086.  
  1087. makeobjs:                         ; make all objects, unrolled loop
  1088.            xor esi,esi
  1089.            i=0
  1090.  
  1091.            rept maxobjects
  1092.            local itsoff
  1093.  
  1094.            mov eax,32767          ; in case of abort
  1095.            mov si,makeorder+i*2
  1096.            test onoff[esi],mainobject_on ; check on/off
  1097.            jz s itsoff
  1098.  
  1099.            call make1obj
  1100.            mov eax,zedthis        ; get z and save for re_sort
  1101.            xor esi,esi
  1102. itsoff:
  1103.            mov finalzed+i*2,ax
  1104.  
  1105.            i=i+1
  1106.            endm
  1107.  
  1108. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1109. ; Re_sort:Bubble sort for entire objects, fastest when already sorted (assumed)
  1110. ;  In=Out=null
  1111. ; Notes: No need to ever call this routine as makeobjs falls through to here.
  1112. ; This routine sorts the objects make order by the previous Z distance.
  1113. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1114.  
  1115.            basedif equ makeorder-finalzed
  1116.  
  1117. re_sort:
  1118.            mov ecx,maxobjects-1
  1119.            mov edx,offset finalzed-2
  1120.            xor ebx,ebx            ; sort flag
  1121.            xor esi,esi
  1122. nextccx:
  1123.            add edx,2
  1124.            mov esi,maxobjects*2-2+offset finalzed
  1125. nextddx:
  1126.            sub esi,2
  1127.  
  1128.            mov ax,[esi+2]
  1129.            cmp ax,[esi]
  1130.            jle s donotng
  1131.            xchg ax,[esi]          ; don't flip entire object, just indexers
  1132.            xchg ax,[esi+2]
  1133.            mov ax,basedif[esi+2]
  1134.            xchg ax,basedif[esi]
  1135.            xchg ax,basedif[esi+2]
  1136.            inc ebx                ; flag that one sorted
  1137. donotng:
  1138.            cmp esi,edx
  1139.            jnle s nextddx
  1140.  
  1141.            or ebx,ebx             ; re-sort until no more sorts
  1142.            loopne s nextccx
  1143. quickex:
  1144.            ret
  1145.  
  1146. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1147. ; Init_tables: Initialize ordering before beginning 3d animation
  1148. ;  In=Out=null
  1149. ; Notes: Called by YOU. Different routines between 3d1,3d2 and 3d3
  1150. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1151.  
  1152. init_tables:
  1153.            call set_makeorder
  1154.            ret
  1155.  
  1156. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1157. ; Flush_surfaces: Sort and flush all surfaces from polygon buffer to screen
  1158. ;  In=Out=null
  1159. ; Notes: called by make1obj
  1160. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1161.  
  1162. flush_surfaces:
  1163.            call sort_list     ; sort sides according to z distance
  1164.            call drawvect      ; draw 'em on da screen
  1165.            ret
  1166.  
  1167. code32     ends
  1168.            end
  1169.